package model.doe;

public class FocusatorKrest extends AbstractDoe {

	private double rad;
	private double f;
	private double d;
	private double wl;
	private double angle;
	private double doeStep;
	private boolean addLen;
	private double cos;
	private double min;
	private double max;

	public FocusatorKrest(double rad, double f, double d, double wl, double angle, double doeStep, boolean addLen) {
		this.rad = rad;
		this.f = f;
		this.d = d;
		this.wl = wl/1000;
		this.angle = angle;
		this.doeStep = doeStep;
		this.addLen = addLen;

		this.cos = Math.cos(angle * Math.PI / 180);
		super.widthPointsNumber = (int) (2*rad / doeStep);
		super.heightPointsNumber = (int) (2*rad / doeStep);
		krestMinMax();
	}

	private double calculate(double u, double v) {
		if (Math.sqrt(u * cos * u * cos + v * v) > rad)
			return 0;
		
		return KrestFun(cos * u, v);

	}


	private void krestMinMax() {

		if (!addLen) {
			super.minValue = 0;
			super.maximumValue = KrestFun(rad / 1.41426, rad / 1.41426);
		}

		else {
			super.minValue = -Math.PI * rad * rad / (wl * f);
			super.maximumValue = Math.PI;
		}

	}

	double KrestFun(double ul, double vl) {

		double c, ph, ph1, ph2, rez;

		// int id, id1;

		c = 2 * Math.PI / (wl * f);

		if (Math.sqrt(ul * ul + vl * vl) <= rad)

		{

			ph1 = (c * .75 * d / Math.pow(rad, 3)) * (.5 * Math.pow(vl * rad, 2) - Math.pow(vl, 4) / 12);

			ph2 = (c * .75 * d / Math.pow(rad, 3)) * (.5 * Math.pow(ul * rad, 2) - Math.pow(ul, 4) / 12);

			ph = .5 * (ph1 + ph2);

			ph1 = .5 * (ph1 - ph2 + (c * .75 * d / Math.pow(rad, 3))
					* (.5 * Math.pow(rad * rad, 2) - Math.pow(rad, 4) / 12));

			ph1 = ((ph1 % (2 * Math.PI)) > Math.PI) ? Math.PI : 0;

			rez = ph + ph1;

		}

		else
			rez = 0;

		if (!addLen)
			return rez;

		else
			return (rez - c * (ul * ul + vl * vl) / 2);

	}

	@Override
	public double run(int i, int j) {		
		return calculate(doeStep * i, doeStep * j);
	}
}
